//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/******************************************************************************
**
**  COPYRIGHT (C) 2000, 2002 Intel Corporation.
**
**  This software as well as the software described in it is furnished under 
**  license and may only be used or copied in accordance with the terms of the 
**  license. The information in this file is furnished for informational use 
**  only, is subject to change without notice, and should not be construed as 
**  a commitment by Intel Corporation. Intel Corporation assumes no 
**  responsibility or liability for any errors or inaccuracies that may appear 
**  in this document or any software that may be provided in association with 
**  this document. 
**  Except as permitted by such license, no part of this document may be 
**  reproduced, stored in a retrieval system, or transmitted in any form or by 
**  any means without the express written consent of Intel Corporation. 
**
**  FILENAME:       xllp_msl.h
**
**  PURPOSE:        This is the main header file for XLLP primitives for the 
**					Mobile Scalable Link (MSL) bus.
**
******************************************************************************/

#ifndef _xllp_msl_h_
#define _xllp_msl_h_

//
//	HEADER FILES
//
#include "xllp_defs.h"


//
// Register addresses
//
#define BASE_ADDRESS_FIFO_REGISTERS		(BASE_ADDRESS_MSL_REGISTERS + CHANNEL_FIFO_REGISTER_OFFSET)
#define BASE_ADDRESS_CONFIG_REGISTERS	(BASE_ADDRESS_MSL_REGISTERS + CHANNEL_CONFIG_REGISTER_OFFSET)
#define BASE_ADDRESS_STATUS_REGISTERS	(BASE_ADDRESS_MSL_REGISTERS + CHANNEL_STATUS_REGISTER_OFFSET)
#define BASE_ADDRESS_EOM_REGISTERS		(BASE_ADDRESS_MSL_REGISTERS + CHANNEL_EOM_REGISTER_OFFSET)
#define BASE_ADDRESS_CONTROL_REGISTERS	(BASE_ADDRESS_MSL_REGISTERS + CHANNEL_CONTROL_REGISTER_OFFSET)

//
// Number of logical data channels in each of outbound and inbound links
// for defining MSL register map
// This should probably remain constant across all hardware ASICS (Bulverde, Manitoba, etc.)
// that use MSL.
// MSL registers for a particular channel are likely to be at the same address location across
// all ASICS
//
#define MSL_NUM_CHANNEL_ADDRESSES		7

//
// Offset in between the addresses of the MSL FIFO register
//
#define MSL_FIFO_OFFSET                 4

//
// Channel Receive/Transmit FIFO register	
//
typedef struct
{
	XLLP_VUINT32_T	BBFIFO[MSL_NUM_CHANNEL_ADDRESSES];		

} XllpFifoRegT, *P_XllpFifoRegT;

//
// Channel configuration register
//
typedef struct
{
	XLLP_VUINT32_T	BBCFG[MSL_NUM_CHANNEL_ADDRESSES];			

} XllpConfigRegT, *P_XllpConfigRegT;

//
// Channel status register
//
typedef struct
{
	XLLP_VUINT32_T	BBSTAT[MSL_NUM_CHANNEL_ADDRESSES];		

} XllpStatusRegT, *P_XllpStatusRegT;

//
// Channel EOM register
//
typedef struct
{
	XLLP_VUINT32_T	BBEOM[MSL_NUM_CHANNEL_ADDRESSES];			

} XllpEomRegT, *P_XllpEomRegT;

typedef struct
{
	XLLP_VUINT32_T	BBCSTP;		// Channel Stop Threshold Register
	XLLP_VUINT32_T	BBCSTR;		// Channel Start Threshold Register
	XLLP_VUINT32_T	BBIID;		// Standard Interface Interrupt ID Register
	XLLP_UINT32_T	Reserved1;	
	XLLP_VUINT32_T	BBFREQ;		// Transmit frequency Select Register
	XLLP_VUINT32_T	BBWAIT;		// Wait Count Register
	XLLP_VUINT32_T	BBCST;		// Clock Stop Time Register
	XLLP_VUINT32_T	BBVGIL;		// Virtual GPIO Input Pin Level Register
	XLLP_VUINT32_T	BBVGOL;		// Virtual GPIO Output Pin Level Register
	XLLP_VUINT32_T	BBVGSR;		// Virtual GPIO Output Pin Set Register
	XLLP_VUINT32_T	BBVGCR;		// Virtual GPIO Output Pin Clear Register
	XLLP_VUINT32_T	BBVGRE;		// Virtual GPIO Rising Edge Detect Register
	XLLP_VUINT32_T	BBVGFE;		// Virtual GPIO Falling Edge Detect Register
	XLLP_VUINT32_T	BBVGED;		// Virtual GPIO Edge Detect Status Register
	XLLP_VUINT32_T	BBVGVI;		// Virtual GPIO Value Interrupt Register
	XLLP_UINT32_T	Reserved2;	
	XLLP_VUINT32_T	BBWAKE;		// Wake up Register
	XLLP_VUINT32_T	BBITFC;		// Interface width register

} XllpControlRegT, *P_XllpControlRegT;



typedef struct
{
    XLLP_UINT32_T	        Reserved1;	
	XllpFifoRegT			FifoReg;		// Fifo Registers
    XLLP_UINT32_T	        Reserved2[9];
	XllpConfigRegT		    ConfigReg;		// Config Registers
    XLLP_UINT32_T	        Reserved3[9];
	XllpStatusRegT		    StatusReg;		// Status Registers
    XLLP_UINT32_T	        Reserved4[9];	
	XllpEomRegT			    EomReg;			// EOM Registers
    XLLP_UINT32_T	        Reserved5[8];	
	XllpControlRegT		    ControlReg;		// Control Registers

} XllpMslRegT, *P_XllpMslRegT;

//
// Register Bit fields
//

//
// Channel Configuration Register (BBCFG) bitfields
//
#define XLLP_MSL_BBCFG_TxEnable			(0)		// Transmit FIFO Channel Enable
#define XLLP_MSL_BBCFG_TxMFCEnable		(1)		// Transmit Message Flow Control Enable
#define XLLP_MSL_BBCFG_TxDFCEnable		(2)		// Transmit Direct Flow Control Enable
#define XLLP_MSL_BBCFG_TxThreshLevel	(3)		// Transmit FIFO Service Threshold
#define XLLP_MSL_BBCFG_TxService		(5)		// Transmit FIFO Service Select
#define XLLP_MSL_BBCFG_TxBlock			(8)		// Transmit Block Size
#define XLLP_MSL_BBCFG_RxEnable			(16)	// Receive FIFO Channel Enable
#define XLLP_MSL_BBCFG_RxMFCEnable		(17)	// Receive Message Flow Control Enable
#define XLLP_MSL_BBCFG_RxDFCEnable		(18)	// Receive Direct Flow Control Enable
#define XLLP_MSL_BBCFG_RxThreshLevel	(19)	// Receive FIFO Service Threshold
#define XLLP_MSL_BBCFG_RxService		(21)	// Receive FIFO Service Select
#define XLLP_MSL_BBCFG_EOCService		(24)	// Early EOC Service Select


//
// Channel Status Register (BBCFG) bitfields
//
#define XLLP_MSL_BBSTAT_TxFullness		(0x1U << 0)		// Fullness of Transmit FIFO 
#define XLLP_MSL_BBSTAT_TxFull			(0x1U << 6)		// Transmit FIFO full
#define XLLP_MSL_BBSTAT_TxEmpty			(0x1U << 7)		// Transmit FIFO Empty
#define XLLP_MSL_BBSTAT_TxWait			(0x1U << 8)		// Transmit channel in WAIT state
#define XLLP_MSL_BBSTAT_RxFullness		(0x1U << 16)	// Fullness of Receive FIFO 
#define XLLP_MSL_BBSTAT_RxFull			(0x1U << 22)	// Receive FIFO full
#define XLLP_MSL_BBSTAT_RxEmpty			(0x1U << 23)	// Receive FIFO Empty
#define XLLP_MSL_BBSTAT_RxWait			(0x1U << 24)	// Receive channel in WAIT state
#define XLLP_MSL_BBSTAT_RxEomFifo		(0x1U << 25)	// Receive channel received EOM
#define XLLP_MSL_BBSTAT_RxEom_1			(0x1U << 28)	// Next byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_2			(0x1U << 29)	// Second byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_3			(0x1U << 30)	// Third byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_4			(0x1U << 31)	// Fourth byte to be read from FIFO is last byte in msg


//
// Standard interface interrupt (BBIID) Register bitfields
//
#define XLLP_MSL_BBIID_VGPIO_INT		(0x1U << 0)			// VGPIO Interrupt
#define XLLP_MSL_BBIID_RX_INT(ch)		(0x1U << (1+ch))	// Receive FIFO interrupt for channel (0<=ch<7)
#define XLLP_MSL_BBIID_EOC_INT(ch)		(0x1U << (9+ch))	// EOC interrupt for channel (ch)
#define XLLP_MSL_BBIID_TX_INT(ch)		(0x1U << (17+ch))	// Transmit FIFO interrupt for channel (ch)

//
// Transmit Frequency Select (BBFRQ) Register bitfields
//
#define XLLP_MSL_BBFREQ_DIV				(4)			// BB_INT Clock divider

//
// Interface Width (BBITFC) Register bitfields
//
#define	XLLP_MSL_BBITFC_TXITFC			(00)			// Transmit (outbound) link interface width
#define	XLLP_MSL_BBITFC_RXITFC			(16)			// Receive  (inbound)  link interface width

#define XLLP_MSL_MAX_RX_FIFO            64              // Max number of words in RX FIFO
#define XLLP_MSL_MAX_TX_FIFO            64              // Max number of words in TX FIFO

#define XLLP_MSL_MAX_VGPIO_PINS         32              // Max number of VGPIO pins
//================================================================================

typedef enum
{
	XLLP_FIFO_CHANNEL_DISABLE=0,
	XLLP_FIFO_CHANNEL_ENABLE

} XllpMslChannelEnableTypeT;

typedef enum
{
	XLLP_MFC_DISABLE = 0,
	XLLP_MFC_ENABLE 

} XllpMslMfcEnableTypeT;

typedef enum
{
	XLLP_DFC_DISABLE = 0,
	XLLP_DFC_ENABLE 

} XllpMslDfcEnableTypeT;

typedef enum
{
	XLLP_FIFO_SERVICE_THRESHOLD_4_BYTES = 0 ,
	XLLP_FIFO_SERVICE_THRESHOLD_8_BYTES		,	
	XLLP_FIFO_SERVICE_THRESHOLD_16_BYTES	,
	XLLP_FIFO_SERVICE_THRESHOLD_32_BYTES

} XllpMslFifoSvcThreshTypeT;

typedef enum
{
	XLLP_FIFO_SERVICE_NONE = 0,
	XLLP_FIFO_SERVICE_DMA,
	XLLP_FIFO_SERVICE_INTERRUPT

} XllpMslFifoServiceTypeT;

typedef enum
{
	XLLP_EOC_SERVICE_NONE = 0,
	XLLP_EOC_SERVICE_INTERRUPT

} XllpMslEocServiceTypeT;

typedef enum
{
	XLLP_TX_BLOCK_4_BYTES = 0 ,
	XLLP_TX_BLOCK_8_BYTES     ,
	XLLP_TX_BLOCK_16_BYTES    ,
	XLLP_TX_BLOCK_32_BYTES    	

} XllpMslTxBlockTypeT;

typedef enum
{
	XLLP_INTERFACE_WIDTH_1_BIT = 0,
    XLLP_INTERFACE_WIDTH_2_BIT,
	XLLP_INTERFACE_WIDTH_4_BIT 

} XllpMslInterfaceWidthTypeT;


typedef enum
{
	InputVgpioPin = 0,
	OutputVgpioPin

} XllpVgpioPinTypeT;

typedef enum
{
	VgpioNone = 0,
	VgpioRisingEdge,
	VgpioFallingEdge,
	VgpioRisingAndFallingEdge
} XllpMslVgpioEdgeTypeT;

//
// FUNCTION PROTOTYPES 
//
void XllpMslConfigureBus(		P_XllpMslRegT				pMslRegBase, 
								XLLP_UINT32_T				maxNumChannels,
								XllpMslInterfaceWidthTypeT	interfaceWidth, 
								XLLP_UINT32_T				xmitFreqDivisor,
								XLLP_UINT32_T				clockStopTime,
								XLLP_UINT32_T				mfcStopThreshold,
								XLLP_UINT32_T				mfcStartThreshold,
                                XLLP_UINT32_T               waitTime);

void XllpMslConfigureRxChannel(	P_XllpMslRegT				pMslRegBase, 
								XLLP_INT32_T				channel,
								XllpMslChannelEnableTypeT	rxChannelEnable,
								XllpMslMfcEnableTypeT		rxMfcEnable,
								XllpMslDfcEnableTypeT		rxDfcEnable,
								XllpMslFifoSvcThreshTypeT	fifoSvcThreshold,
								XllpMslFifoServiceTypeT		fifoServiceType,	
								XllpMslEocServiceTypeT		eocServiceType);
						  
void XllpMslConfigureTxChannel(P_XllpMslRegT				pMslRegBase,
							   XLLP_INT32_T					channel,
							   XllpMslChannelEnableTypeT	txChannelEnable,
							   XllpMslMfcEnableTypeT		txMfcEnable,
							   XllpMslDfcEnableTypeT		txDfcEnable,
						       XllpMslFifoSvcThreshTypeT	fifoSvcThreshold,
						       XllpMslFifoServiceTypeT		fifoServiceType);

void XllpMslSetTxFifoService    (P_XllpMslRegT				pMslRegBase,
	                            XLLP_INT32_T				channel,
                                XLLP_UINT32_T               bEnable);

void XllpMslSetRxFifoService    (P_XllpMslRegT				pMslRegBase,
	                            XLLP_INT32_T				channel,
                                XLLP_UINT32_T               bEnable);

void XllpMslDisableTxFifoService(P_XllpMslRegT				pMslRegBase,
	                            XLLP_INT32_T				channel);

void XllpMslEmptyRxFifo       (P_XllpMslRegT				pMslRegBase, 
	                           XLLP_INT32_T				    channel);

void XllpMslGetChannelStatus  ( P_XllpMslRegT				pMslRegBase,
		  						XLLP_INT32_T				channel,
								XLLP_UINT32_T				*status);


void XllpMslGetInterruptStatus(P_XllpMslRegT				pMslRegBase,
							   XLLP_UINT32_T				*interruptStatus);
void XllpMslClearInterrupts	  (P_XllpMslRegT				pMslRegBase,
							   XLLP_UINT32_T				interruptMask);

void XllpMslSendWake		   (P_XllpMslRegT				pMslRegBase );
void XllpMslSendEOM			   (P_XllpMslRegT				pMslRegBase,
								XLLP_UINT32_T				channel);

XLLP_LEVEL_T XllpMslGetVgpioLevel	   (P_XllpMslRegT				pMslRegBase,
								XllpVgpioPinTypeT			pinType,
								XLLP_UINT32_T				pinNumber);

void XllpMslSetVgpioLevel	   (P_XllpMslRegT				pMslRegBase,
								XLLP_UINT32_T				pinNumber,
								XLLP_LEVEL_T				pinLevel);

						  
void XllpMslConfigureVgpioEdgeDetect(P_XllpMslRegT			pMslRegBase,
									 XLLP_UINT32_T			outputPinNumber,
									 XllpMslVgpioEdgeTypeT	pinEdgeType);

XLLP_BOOL_T XllpMslGetVgpioEdgeStatus (P_XllpMslRegT		pMslRegBase,
								XLLP_UINT32_T				inputPinNumber);
	
void XllpMslConfigureVgpioInterrupt(P_XllpMslRegT			pMslRegBase,
									XLLP_CONTROL_T			offOrOn);




__inline void XllpMslByteWrite 
(
    P_XllpMslRegT			pMslRegBase,
    XLLP_INT32_T            chan, 
    XLLP_UINT8_T            data
)
{
	*((XLLP_UINT8_T*) &pMslRegBase->FifoReg.BBFIFO[chan]) = data;
}

__inline XLLP_UINT8_T XllpMslByteRead 
(
    P_XllpMslRegT			pMslRegBase,
    XLLP_INT32_T            chan
)
{
	return (*((XLLP_UINT8_T*)&pMslRegBase->FifoReg.BBFIFO[chan]) & 0xFF);
}

__inline void XllpMslWordWrite 
(
    P_XllpMslRegT			pMslRegBase,
    XLLP_INT32_T            chan, 
    XLLP_UINT32_T           data
)
{
	pMslRegBase->FifoReg.BBFIFO[chan] = data;
}

__inline XLLP_UINT32_T XllpMslWordRead 
(
    P_XllpMslRegT			pMslRegBase,
    XLLP_INT32_T            chan
)
{
	return (pMslRegBase->FifoReg.BBFIFO[chan]);
}

#endif // _xllp_msl_h_
